package fr.imag.m2pgi.m2m.geoloc.visualizer;

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.LineArray;
import javax.media.j3d.Shape3D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.ListModel;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;

import static java.lang.Math.*;

import com.sun.j3d.utils.universe.SimpleUniverse;

public class VisuaImpl2 extends JPanel implements Visualizer {

  /**
   * 
   */
  private static final long serialVersionUID = -4476186403766465770L;

  private int zmax;
  private Map<Integer, Map<Double, Integer>> listeMeasure = new HashMap<Integer, Map<Double, Integer>>();
  private Canvas3D canvas;
  private SimpleUniverse simpleU;
  private BranchGroup previous;

  public VisuaImpl2(int z) {
    this.setLayout(new BorderLayout());

    // creation de la scene java3d
    canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
    simpleU = new SimpleUniverse(canvas);
    BranchGroup visua = new BranchGroup();
    visua.setCapability(BranchGroup.ALLOW_DETACH);
    visua.compile();
    simpleU.addBranchGraph(visua);
    simpleU.getViewingPlatform().setNominalViewingTransform();
    this.add(canvas);

    init(z);
  }

  public void addMeasure(Map<Double, Integer> data, int z) {
    listeMeasure.put(z, data);
    // Canvas3D prevCanvas = canvas;
    // canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
    // canvas.setSize(canvas.getParent().getSize());
    // SimpleUniverse simpleU = new SimpleUniverse(canvas);
    BranchGroup visua = new BranchGroup();

    // double dz;
    // LineArray lPaire = new LineArray(2, LineArray.COORDINATES
    // | LineArray.COLOR_3);
    // LineArray lImpaire = new LineArray(2, LineArray.COORDINATES
    // | LineArray.COLOR_3);

    drawMeasure(visua, z, data);

    visua.setCapability(BranchGroup.ALLOW_DETACH);
    visua.compile();
    if (previous != null) {
      simpleU.getLocale().replaceBranchGraph(previous, visua);
      previous = visua;
    } else {
      // simpleU.getViewingPlatform().setNominalViewingTransform();
      simpleU.addBranchGraph(visua);
    }
    // this.remove(prevCanvas);
    // this.add(canvas, 0);
    canvas.setVisible(true);
    setVisible(true);
    repaint();
    // this.getParent().repaint();
  }

  private void drawMeasure(BranchGroup visua, int z, Map<Double, Integer> map) {
    LineArray lPaire = new LineArray(2, LineArray.COORDINATES|LineArray.COLOR_3);
    LineArray lImpaire = new LineArray(2, LineArray.COORDINATES|LineArray.COLOR_3);
    double dz;
    dz = 1 - (double) z / (double) zmax;

    List<Double> liste = new ArrayList<Double>(map.keySet());
    Collections.sort(liste);

    for (int j = 0; j < liste.size(); j++) {

      double angle = liste.get(j);
      // System.out.println(angle);
      int distance = map.get(angle);
      // System.out.println(distance);
      double x = 0.0, y = 0.0;

      x = (sin(toRadians(angle))*distance)/5000;
      y = (cos(toRadians(angle))*distance)/5000;
      
//      if (angle > 0.0) {
//        x = Math.abs(Math.cos(Math.abs(angle - 90.0)) * distance / 5000);
//      }
//      if (angle == 0.0) {
//        x = 0.0;
//      }
//      if (angle < 0.0) {
//        x = -Math.abs(Math.cos(Math.abs(angle + 90.0)) * distance / 5000);
//      }
//
//      // calcul pour y
//      if (-90.0 < angle && angle < 90.0) {
//        y = Math.abs(Math.cos(Math.abs(angle)) * distance / 5000);
//      }
//      if (Math.abs(angle) == 90.0) {
//        y = 0.0;
//      }
//      if (angle < -90.0) {
//        y = -Math.abs(Math.cos(Math.abs(angle - 90.0)) * distance / 5000);
//      }
//      if (angle > 90.0) {
//        y = -Math.abs(Math.cos(Math.abs(angle + 90.0)) * distance / 5000);
//      }

      if (j % 2 == 0) {
        if (j != liste.size() - 1) {
          lPaire = new LineArray(2, LineArray.COORDINATES | LineArray.COLOR_3);
          lPaire.setCoordinate(0, new Point3d(x, y, dz));
          lPaire.setColor(0, new Color3f(1f, 0f, 0f));
        }

        if (j != 0) {
          lImpaire.setCoordinate(1, new Point3d(x, y, dz));
          lImpaire.setColor(1, new Color3f(1f, 0f, 0f));
          visua.addChild(new Shape3D(lImpaire));
        }
      }
      if (j % 2 == 1) {
        if (j != liste.size() - 1) {
          lImpaire = new LineArray(2, LineArray.COORDINATES | LineArray.COLOR_3);
          lImpaire.setCoordinate(0, new Point3d(x, y, dz));
          lImpaire.setColor(0, new Color3f(1f, 0f, 0f));
        }
        lPaire.setCoordinate(1, new Point3d(x, y, dz));
        lPaire.setColor(1, new Color3f(1f, 0f, 0f));
        visua.addChild(new Shape3D(lPaire));

      }

      System.out.println("(" + x + " ; " + y + " ; " + dz + ")");

    }// for j
  }

  public void init(int z) {
    // Initialisation de la fenêtre
    zmax = z;
    listeMeasure = new HashMap<Integer, Map<Double, Integer>>();
//    setSize(400, 400);
    setVisible(true);
  }

  public void reset() {
    // TODO Auto-generated method stub

  }

  public static void main(final String args[]) {
    Frame frame = new Frame("Test");
    frame.setSize(640, 480);
    VisuaImpl2 visual = new VisuaImpl2(100);
    visual.setSize(640, 480);
    frame.setLayout(new BorderLayout());
    frame.add(visual);
    frame.setVisible(true);
    // visual.setVisible(true);

    Map<Double, Integer> map = new HashMap<Double, Integer>();
    map.put(-180.0, 1000);
    map.put(-135.0, 1414);
    map.put( -90.0, 1000);
    map.put( -45.0, 1414);
    map.put(  45.0, 1414);
    map.put(  90.0, 1000);
    map.put( 135.0, 1414);
    map.put( 180.0, 1000);
    for (int i = 0; i < 102; i = i + 2) {
      visual.addMeasure(map, i);
//      frame.repaint();
//      visual.setVisible(true);
//      frame.setVisible(true);
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
    // visual.setVisible(true);
    // visual.setVisible(true);
    // visual.setVisible(true);
    // visual.setVisible(true);
    // visual.addMeasure(map,3);
    // Thread.sleep(1000);
    // visual.addMeasure(map,15);
    // Thread.sleep(1000);
    // visual.setVisible(true);

  }

}
